<?php
// +----------------------------------------------------------------------
// | B5YiiCMF
// +----------------------------------------------------------------------
// | Author: 李恒 <357145480@qq.com>
// +----------------------------------------------------------------------
namespace common\helpers;

use yii\db\Exception;

class TransformApi
{

    /**
     * 获取年龄
     * @param $start
     * @param $end
     * @return bool|int|mixed
     */
    public static function getAge($start, $end = '')
    {
        if (!$start) return false;
        $start = strtotime($start);
        if ($start === false) return false;

        if ($end) {
            $end = strtotime($end);
            if ($end === false) return false;
        } else {
            $end = time();
        }
        if ($end < $start) return false;
        list($y1, $m1, $d1) = explode("-", date("Y-m-d", $start));
        list($y2, $m2, $d2) = explode("-", date("Y-m-d", $end));
        $age = $y2 - $y1;
        if ((int)($m2 . $d2) < (int)($m1 . $d1))
            $age -= 1;
        return $age;
    }

    /**
     * 时间处理
     * @param $timestamp
     * @return false|string
     */
    public static function timeAgo($timestamp)
    {
        $counttime = time() - $timestamp;//相差时间戳
        if ($counttime <= 60) {
            return '刚刚';
        } else if ($counttime < 3600) {
            return intval(($counttime / 60)) . '分钟前';
        } else if ($counttime >= 3600 && $counttime < 3600 * 24) {
            return intval(($counttime / 3600)) . '小时前';
        } else if ($counttime <= 3600 * 24 * 10) {
            return intval(($counttime / (3600 * 24))) . '天前';
        } else {
            return date('Y-m-d', $timestamp);
        }
    }

    /**
     * 容量显示
     * @param $size
     * @return string
     */
    public static function sizeShow($size)
    {
        $size = intval($size);
        if ($size < 0) return '';
        $coin = 'Byte';
        $number = 0;
        $b_size = 1024;
        $kb_size = $b_size * 1024;
        $mb_size = $kb_size * 1024;
        $gb_size = $mb_size * 1024;
        if ($size >= 0 && $size < $b_size) {
            $number = $size;
        } elseif ($size >= $b_size && $size < $mb_size) {
            $number = floor(($size / $b_size) * 100) / 100;
            $coin = 'KB';
        } elseif ($size >= $mb_size && $size < $gb_size) {
            $number = floor(($size / $mb_size) * 100) / 100;
            $coin = 'MB';
        } else {
            $number = floor(($size / $gb_size) * 100) / 100;
            $coin = 'GB';
        }
        return $number . $coin;
    }

    /**
     * 加密函数
     * @param $txt 加密字符串
     * @param string $key 钥匙
     * @return string
     */
    public static function lockUrl($txt,$key='ea68d19584c905f2f691263c5c6780e2'){
        $chars = "ABCDEFGHIJKLMNOPQRSTUVWXYZabcdefghijklmnopqrstuvwxyz0123456789-=+";
        $nh = rand(0,64);
        $ch = $chars[$nh];
        $mdKey = md5($key.$ch);
        $mdKey = substr($mdKey,$nh%8, $nh%8+7);
        $txt = base64_encode($txt);
        $tmp = '';
        $i=0;$j=0;$k = 0;
        for ($i=0; $i<strlen($txt); $i++) {
            $k = $k == strlen($mdKey) ? 0 : $k;
            $j = ($nh+strpos($chars,$txt[$i])+ord($mdKey[$k++]))%64;
            $tmp .= $chars[$j];
        }
        return urlencode($ch.$tmp);
    }

    /**
     * 解密函数
     * @param $txt 解密字符串
     * @param string $key 钥匙
     * @return false|string
     */
    public static function unlockUrl($txt,$key='ea68d19584c905f2f691263c5c6780e2'){
        $txt = urldecode($txt);
        $chars = "ABCDEFGHIJKLMNOPQRSTUVWXYZabcdefghijklmnopqrstuvwxyz0123456789-=+";
        $ch = $txt[0];
        $nh = strpos($chars,$ch);
        $mdKey = md5($key.$ch);
        $mdKey = substr($mdKey,$nh%8, $nh%8+7);
        $txt = substr($txt,1);
        $tmp = '';
        $i=0;$j=0; $k = 0;
        for ($i=0; $i<strlen($txt); $i++) {
            $k = $k == strlen($mdKey) ? 0 : $k;
            $j = strpos($chars,$txt[$i])-$nh - ord($mdKey[$k++]);
            while ($j<0) $j+=64;
            $tmp .= $chars[$j];
        }
        return base64_decode($tmp);
    }

    /**
     * 计算两点地理坐标之间的距离
     * @param Decimal $longitude1 起点经度
     * @param Decimal $latitude1 起点纬度
     * @param Decimal $longitude2 终点经度
     * @param Decimal $latitude2 终点纬度
     * @param Int $unit 单位 1:米 2:公里
     * @param Int $decimal 精度 保留小数位数
     * @return Decimal
     */
    public static function getDistance($longitude1, $latitude1, $longitude2, $latitude2, $unit = 2, $decimal = 2)
    {
        $EARTH_RADIUS = 6370.996; // 地球半径系数
        $PI = 3.1415926;
        $radLat1 = $latitude1 * $PI / 180.0;
        $radLat2 = $latitude2 * $PI / 180.0;
        $radLng1 = $longitude1 * $PI / 180.0;
        $radLng2 = $longitude2 * $PI / 180.0;
        $a = $radLat1 - $radLat2;
        $b = $radLng1 - $radLng2;
        $distance = 2 * asin(sqrt(pow(sin($a / 2), 2) + cos($radLat1) * cos($radLat2) * pow(sin($b / 2), 2)));
        $distance = $distance * $EARTH_RADIUS * 1000;
        if ($unit == 2) {
            $distance = $distance / 1000;
        }
        return round($distance, $decimal);
    }

    /**
     * 统一事物
     * @param callable $fun
     * @param $result
     * @param $db
     */
    public static function tx(callable $fun, &$result, $db = 'db')
    {
        $tran = \Yii::$app->{$db}->beginTransaction();
        try {
            $result = $fun();
            $tran->commit();
        } catch (Exception $e) {
            $tran->rollBack();
            $result = commonApi::message($e->getMessage(), false);
        }
        return true;
    }

    /**
     * 地址逆解析
     * @param $addr 地址
     * @return array
     */
    public static function addressAnalysis($addr)
    {
        $key = '7ec1defb572428f69ce699450568e580';
        $res = commonApi::b5curl_get("https://restapi.amap.com/v3/geocode/geo?address={$addr}&key=$key");
        $res = json_decode($res,true);
        if (empty($res['geocodes'][0]['location'])){
            return commonApi::message('地址解析失败！',false);
        }
        $location = $res['geocodes'][0]['location'];
        $res1 = commonApi::b5curl_get("https://restapi.amap.com/v3/geocode/regeo?location={$location}&key=$key");
        $res1 = json_decode($res1,true);
        if (empty($res1['regeocode']['addressComponent'])){
            return commonApi::message('地址解析失败！！！');
        }
        $locationArr = explode(',',$location);
        $formatted_address = $res['geocodes'][0]['formatted_address'];
        $data['long'] = $locationArr[0];
        $data['lat'] = $locationArr[1];
        $data['province'] = $res1['regeocode']['addressComponent']['province'];
        $data['city'] = $res1['regeocode']['addressComponent']['city'];
        $data['county'] = $res1['regeocode']['addressComponent']['district'];
        $data['street'] = $res1['regeocode']['addressComponent']['township'];
        $formatted_address = str_replace($data['province'], '', $formatted_address);
        $formatted_address = str_replace($data['city'], '', $formatted_address);
        $formatted_address = str_replace($data['county'], '', $formatted_address);
        $data['address'] = str_replace($data['street'], '', $formatted_address);
        return commonApi::message('成功',true,$data);
    }

    /**
     * 金额小数点精确
     * @param $value
     * @param int $digit
     * @return float|int
     */
    public static function decimalPoint($value, $digit = 2)
    {
        $result = intval(bcmul($value, pow(10, $digit))) / pow(10, $digit);
        return $result;
    }

    /**
     * 值是否在范围内
     * @param $min 最小值
     * @param $max 最大值
     * @param string $time 当前值
     * @return bool
     */
    public static function testingTimeRange($min, $max, $time = '')
    {
        if (empty($min) || empty($max)) {
            return false;
        }
        $time = empty($time) ? time() : $time;
        if ($min <= $time && $time <= $max) {
            return true;
        }
        return false;
    }

    /**
     * 批量修改sql
     * @param $table 表名
     * @param $rows 要修改的字段
     * @param $keyPrimaryArrs 标识
     * @param string $id
     * @return string
     */
    public static function batchUpdate($table, $rows, $keyPrimaryArrs,$id='id')
    {
        //查询数据库返回的数据格式
        $newhouse_clicks = $rows;
        //拼接批量更新sql语句
        $sql = "UPDATE $table SET ";
        //合成sql语句
        $one = current($newhouse_clicks);
        foreach ($one as $key => $value) {
            $sql .= "`{$key}` = CASE $id ";
            foreach ($newhouse_clicks as $k => $val) {
                if (strpos($val[$key],'`')!==false){
                    $sql .= "WHEN $keyPrimaryArrs[$k] THEN $val[$key] ";
                }else{
                    $sql .= "WHEN $keyPrimaryArrs[$k] THEN '$val[$key]'";
                }
            }
            $sql .= "END, ";
        }
        //把最后一个,去掉
        $sql = substr($sql, 0, strrpos($sql, ','));
        //合并所有id
        $ids = implode(',', $keyPrimaryArrs);
        //拼接sql
        $sql .= " WHERE $id IN ({$ids})";
        //测试自动提交hah
        return $sql;
    }
}